/*
 * The contents of this file are subject to the Mozilla Public License
 * Version 1.1 (the "License");  you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * http//www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
 * the specific language governing rights and limitations under the License.
 *
 * The Original Code is ART Ontology API.
 *
 * The Initial Developer of the Original Code is University of Roma Tor Vergata.
 * Portions created by University of Roma Tor Vergata are Copyright (C) 2009.
 * All Rights Reserved.
 *
 * The ART Ontology API were developed by the Artificial Intelligence Research Group
 * (art.uniroma2.it) at the University of Roma Tor Vergata
 * Current information about the ART Ontology API can be obtained at 
 * http//art.uniroma2.it/owlart
 *
 */

/*
 * Contributor(s): Armando Stellato stellato@info.uniroma2.it
 */
package it.uniroma2.art.owlart.models;

import it.uniroma2.art.owlart.exceptions.ModelAccessException;
import it.uniroma2.art.owlart.exceptions.ModelUpdateException;
import it.uniroma2.art.owlart.model.ARTResource;
import it.uniroma2.art.owlart.model.ARTURIResource;
import it.uniroma2.art.owlart.navigation.ARTLiteralIterator;
import it.uniroma2.art.owlart.navigation.ARTResourceIterator;
import it.uniroma2.art.owlart.navigation.ARTURIResourceIterator;
import it.uniroma2.art.owlart.vocabulary.RDF;
import it.uniroma2.art.owlart.vocabulary.RDFS;

/**
 * Interface for basic RDFS models<br/>
 * 
 * @author Armando Stellato
 * 
 */
public interface RDFSModel extends RDFModel, RDFSReasoner {

	/**
	 * given class <code>cls</code>, it retrieves all of its named superclasses in an Iterator
	 * 
	 * @param cls
	 * @param inferred
	 * @param graphs
	 * @return
	 * @throws ModelAccessException
	 */
	public abstract ARTURIResourceIterator listURISuperClasses(ARTResource cls, boolean inferred,
			ARTResource... graphs) throws ModelAccessException;

	/**
	 * removes a comment for given <code>resource</code> from the model
	 * 
	 * @param subject
	 * @param label
	 * @param language
	 * @param graphs
	 * @throws ModelUpdateException
	 */
	public void removeComment(ARTResource resource, String label, String language, ARTResource... graphs)
			throws ModelUpdateException;

	/**
	 * removes a label for given <code>resource</code> from the model
	 * 
	 * @param subject
	 * @param label
	 * @param language
	 * @param graphs
	 * @throws ModelUpdateException
	 */
	public void removeLabel(ARTResource resource, String label, String language, ARTResource... graphs)
			throws ModelUpdateException;

	/**
	 * removes a domain statement between <code>property</code> and <code>domain</code> beware:
	 * <code>property</code> should already be part of the repository!
	 * 
	 * @param property
	 * @param domain
	 * @param graphs
	 * @throws ModelUpdateException
	 */
	public abstract void removePropertyDomain(ARTURIResource property, ARTResource domain,
			ARTResource... graphs) throws ModelUpdateException;

	/**
	 * removes a range statement between <code>property</code> and <code>range</code> beware:
	 * <code>property</code> should already be part of the repository!
	 * 
	 * @param property
	 * @param range
	 * @throws ModelUpdateException
	 */
	public abstract void removePropertyRange(ARTURIResource property, ARTResource range,
			ARTResource... graphs) throws ModelUpdateException;

	/**
	 * removes a subPropertyOf statement between <code>property</code> and <code>superProp</code> beware:
	 * <code>property</code> should already be part of the repository!
	 * 
	 * @param property
	 * @param superProp
	 * @throws ModelUpdateException
	 */
	public abstract void removeSuperProperty(ARTResource property, ARTResource superProp,
			ARTResource... graphs) throws ModelUpdateException;

	/**
	 * This method has a different behavior depending on the level of the vocabulary used by the repository
	 * implementation. The newly created class will be an rdfs:Class in RDFS repositories and owl:Class in OWL
	 * repositories
	 * 
	 * @param uri
	 *            URI string of the class being created
	 */
	public abstract void addClass(String uri, ARTResource... graphs) throws ModelUpdateException;

	/**
	 * Adds <code>label</code> to <code>subject</code> in the given language <code>language</code>
	 * 
	 * @param subject
	 * @param label
	 * @param language
	 */
	public abstract void addComment(ARTResource subject, String label, String language, ARTResource... graphs)
			throws ModelUpdateException;

	/**
	 * adds a domain statement between <code>property</code> and <code>domain</code> beware:
	 * <code>property</code> should already be part of the repository!
	 * 
	 * @param property
	 * @param domain
	 * @throws ModelUpdateException
	 */
	public abstract void addPropertyDomain(ARTURIResource property, ARTResource domain, ARTResource... graphs)
			throws ModelUpdateException;

	/**
	 * adds a range statement between <code>property</code> and <code>range</code> beware:
	 * <code>property</code> should already be part of the repository!
	 * 
	 * @param property
	 * @param range
	 * @throws ModelUpdateException
	 */
	public abstract void addPropertyRange(ARTURIResource property, ARTResource range, ARTResource... graphs)
			throws ModelUpdateException;

	/**
	 * Adds <code>label</code> to <code>subject</code> in the given language <code>language</code>
	 * 
	 * @param subject
	 * @param label
	 * @param language
	 */
	public abstract void addLabel(ARTResource subject, String label, String language, ARTResource... graphs)
			throws ModelUpdateException;

	public abstract void addSuperClass(ARTResource cls, ARTResource supercls, ARTResource... graphs)
			throws ModelUpdateException;

	/**
	 * adds a subPropertyOf statement between <code>property</code> and <code>superProp</code> beware:
	 * <code>property</code> should already be part of the repository!
	 * 
	 * @param property
	 * @param superProp
	 * @throws ModelUpdateException
	 */
	public abstract void addSuperProperty(ARTURIResource property, ARTURIResource superProp,
			ARTResource... graphs) throws ModelUpdateException;

	/**
	 * lists all comments for given {@link ARTResource} <code>res</code>
	 * 
	 * @param res
	 * @param inferred
	 * @param graphs
	 * @return
	 * @throws ModelAccessException
	 */
	public ARTLiteralIterator listComments(ARTResource res, boolean inferred, ARTResource... graphs)
			throws ModelAccessException;

	/**
	 * lists all labels for given {@link ARTResource} <code>res</code>
	 * 
	 * @param res
	 * @param inferred
	 * @param graphs
	 * @return
	 * @throws ModelAccessException
	 */
	public ARTLiteralIterator listLabels(ARTResource res, boolean inferred, ARTResource... graphs)
			throws ModelAccessException;

	/**
	 * returns all the classes which have been declared in the domain of the property
	 * 
	 * @param property
	 *            the property whose domain is being queried
	 * @param inferred
	 * @return the ranges of the property
	 * @throws ModelAccessException
	 */
	public abstract ARTResourceIterator listPropertyDomains(ARTResource property, boolean inferred,
			ARTResource... graphs) throws ModelAccessException;

	/**
	 * as {@link}getPropertyRanges(property, false)
	 * 
	 * @param property
	 *            the property whose range is being queried
	 * @param inferred
	 * @return the ranges of the property
	 * @throws ModelAccessException
	 */
	public abstract ARTResourceIterator listPropertyRanges(ARTResource property, boolean inferred,
			ARTResource... graphs) throws ModelAccessException;

	/**
	 * returns all the properties which see class <code>cls</code> as their domain
	 * 
	 * @param cls
	 * @return
	 */
	public abstract ARTURIResourceIterator listPropertiesForDomainClass(ARTResource cls, boolean inferred,
			ARTResource... graphs) throws ModelAccessException;

	/**
	 * returns all the properties which see class <code>cls</code> as their range
	 * 
	 * @param cls
	 * @return
	 */
	public abstract ARTURIResourceIterator listPropertiesForRangeClass(ARTResource cls, boolean inferred,
			ARTResource... graphs) throws ModelAccessException;

	/**
	 * @param uri
	 * @param graphs
	 * @return
	 * @throws ModelAccessException
	 */
	public abstract ARTURIResource retrieveClass(String uri, ARTResource... graphs)
			throws ModelAccessException;

	/**
	 * list all the classes in the current Model (in graphs: <code>graphs</code>).
	 * If this model is also an {@link RDFSReasoner} which {@link RDFSReasoner#supportsSubClassOfClosure()},
	 * the returned URIs are all rdf instances of {@link RDFS#CLASS}. If negative case, the returned URIs are
	 * those specified as subjects of triples present in the given <code>graphs</code> where the predicate
	 * is {@link RDF#TYPE} or {@link RDFS#SUBCLASSOF}.
	 * 
	 * @param inferred
	 * @return Collection arrayList
	 * @throws ModelAccessException
	 */
	public abstract ARTResourceIterator listClasses(boolean inferred, ARTResource... graphs)
			throws ModelAccessException;
	
	/**
	 * list all the classes in the current Model (in graphs: <code>graphs</code>) which have a name (a URI).
	 * If this model is also an {@link RDFSReasoner} which {@link RDFSReasoner#supportsSubClassOfClosure()},
	 * the returned URIs are all rdf instances of {@link RDFS#CLASS}. If negative case, the returned URIs are
	 * those specified as subjects of triples present in the given <code>graphs</code> where the predicate
	 * is {@link RDF#TYPE} or {@link RDFS#SUBCLASSOF}.
	 * 
	 * @param inferred
	 * @return Collection arrayList
	 * @throws ModelAccessException
	 */
	public abstract ARTURIResourceIterator listNamedClasses(boolean inferred, ARTResource... graphs)
			throws ModelAccessException;

	/**
	 * list all the URI resources in the current Model. If this model is also an {@link RDFSReasoner} which
	 * {@link RDFSReasoner#supportsSubClassOfClosure()}, the returned URIs are all rdf instances of
	 * {@link RDFS#RESOURCE}. If negative case, the returned URIs are those specified as subjects of triples
	 * present in the specified <code>graphs</code>.
	 * 
	 * @param graphs
	 * @return
	 * @throws ModelAccessException
	 */
	public abstract ARTURIResourceIterator listNamedResources(ARTResource... graphs)
			throws ModelAccessException;

	/**
	 * returns all subclasses (also non direct ones) of class <code>cls</code>
	 * 
	 * @param inferred
	 * @param resource
	 * 
	 * @return
	 * @throws ModelAccessException
	 */
	public abstract ARTResourceIterator listSubClasses(ARTResource cls, boolean inferred,
			ARTResource... graphs) throws ModelAccessException;

	/**
	 * returns all superclasses (also non direct ones) of class <code>cls</code>
	 * 
	 * @param inferred
	 *            TODO
	 * @param resource
	 * 
	 * @return
	 * @throws ModelAccessException
	 */
	public abstract ARTResourceIterator listSuperClasses(ARTResource cls, boolean inferred,
			ARTResource... graphs) throws ModelAccessException;

	/**
	 * returns a list of subproperties of <code>resource</code>
	 * 
	 * @param property
	 * @param inferred
	 * @return a list of subproperties of <code>resource</code>
	 * @throws ModelAccessException
	 */
	public ARTURIResourceIterator listSubProperties(ARTURIResource property, boolean inferred,
			ARTResource... graphs) throws ModelAccessException;

	/**
	 * returns a list of superproperties of <code>resource</code>
	 * 
	 * @param property
	 * @param inferred
	 * @return a list of superproperties of <code>resource</code>
	 * @throws ModelAccessException
	 */
	public ARTURIResourceIterator listSuperProperties(ARTURIResource property, boolean inferred,
			ARTResource... graphs) throws ModelAccessException;

	public abstract boolean isClass(ARTResource cls, ARTResource... graphs) throws ModelAccessException;

	public abstract void removeSuperClass(ARTResource cls, ARTResource supercls, ARTResource... graphs)
			throws ModelUpdateException;

	
	public abstract void deleteClass(ARTResource cls, ARTResource... graphs) throws ModelUpdateException;
	
	public abstract void renameClass(ARTURIResource cls, String newURI, ARTResource... graphs) throws ModelUpdateException;

}
